﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
using Miris.HumanMilkAnalyser.Service.Shared;
using Miris.HumanMilkAnalyser.WPF.Model;
using Miris.HumanMilkAnalyser.WPF.Shared;

namespace Miris.HumanMilkAnalyser.WPF.ViewModel
{
    public class DeviceUnassignedSampleNumberListViewModel : MyViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the DeviceUnassignedSampleNumberListViewModel class.
        /// </summary>
        public DeviceUnassignedSampleNumberListViewModel(IDataService dataService)
            : base(dataService) { }

        public override void ResetProperties()
        {
            base.ResetProperties();

            StartDate = GeneralUtility.GetCurrentDateTime();
            EndDate = GeneralUtility.GetCurrentDateTime();
            UnassignedSampleNumberList.Clear();
        }

        /// <summary>
        /// The <see cref="StartDate" /> property's name.
        /// </summary>
        public const string StartDatePropertyName = "StartDate";

        private DateTime _startDate = GeneralUtility.GetCurrentDateTime();

        /// <summary>
        /// Sets and gets the StartDate property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public DateTime StartDate
        {
            get
            {
                return _startDate;
            }

            set
            {
                if (_startDate == value)
                {
                    return;
                }

                RaisePropertyChanging(StartDatePropertyName);
                _startDate = value;
                RaisePropertyChanged(StartDatePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="EndDate" /> property's name.
        /// </summary>
        public const string EndDatePropertyName = "EndDate";

        private DateTime _endDate = GeneralUtility.GetCurrentDateTime();

        /// <summary>
        /// Sets and gets the EndDate property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public DateTime EndDate
        {
            get
            {
                return _endDate;
            }

            set
            {
                if (_endDate == value)
                {
                    return;
                }

                RaisePropertyChanging(EndDatePropertyName);
                _endDate = value;
                RaisePropertyChanged(EndDatePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="UnassignedSampleNumberList" /> property's name.
        /// </summary>
        public const string UnassignedSampleNumberListPropertyName = "UnassignedSampleNumberList";

        private ObservableCollection<UnassignedSampleNumberViewModel> _unassignedSampleNumberList =
            new ObservableCollection<UnassignedSampleNumberViewModel>();

        /// <summary>
        /// Sets and gets the UnassignedSampleNumberList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<UnassignedSampleNumberViewModel> UnassignedSampleNumberList
        {
            get
            {
                return _unassignedSampleNumberList;
            }

            set
            {
                if (_unassignedSampleNumberList == value)
                {
                    return;
                }

                RaisePropertyChanging(UnassignedSampleNumberListPropertyName);
                _unassignedSampleNumberList = value;
                RaisePropertyChanged(UnassignedSampleNumberListPropertyName);
            }
        }

        private RelayCommand _searchCommand;

        /// <summary>
        /// Gets the SearchCommand.
        /// </summary>
        public RelayCommand SearchCommand
        {
            get
            {
                return _searchCommand ?? (_searchCommand = new RelayCommand(
                    ExecuteSearchCommand,
                    CanExecuteSearchCommand));
            }
        }

        private void ExecuteSearchCommand()
        {
            try
            {
                var analysisResultService = ServiceFactory.CreateAnalysisResultService();
                var selectedStartDate = StartDate.Date;
                var selectedEndDate = new DateTime(EndDate.Year, EndDate.Month, EndDate.Day, 23, 59, 59);

                // Get all sample numbers from device.
                var deviceSampleNumberList = ViewModelHelper.RetrieveDeviceAllSampleNumberList(selectedStartDate, selectedEndDate);

                // Get all analysis results.
                var allResults = analysisResultService.GetAll();


                // Filter out all the unassigned sample numbers.
                var deviceUnassignedSampleNumberList = (from s in deviceSampleNumberList
                                                       where !allResults.Any(p => p.SampleNumber == s.SampleNumber)
                                                       select s).ToList();

                // Assign the SequenceNumber.
                for (int i = 0; i < deviceUnassignedSampleNumberList.Count(); i++)
                {
                    deviceUnassignedSampleNumberList[i].SequenceNumber = i + 1;
                }

                UnassignedSampleNumberList = new ObservableCollection<UnassignedSampleNumberViewModel>(deviceUnassignedSampleNumberList);
            }
            catch (Exception ex)
            {
                RequestDisplayErrorMessage(ex.Message);
            }
        }

        private bool CanExecuteSearchCommand()
        {
            // If StartDate is less than or equal than EndDate.
            return StartDate <= EndDate;
        }
    }
}
